package com.dbms.parser.ast;

import com.dbms.common.Position;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 代表SQL UPDATE语句的抽象语法树（AST）节点。
 * <p>
 * 该节点封装了UPDATE语句的所有关键部分，包括目标表名、
 * SET子句中的赋值表达式以及可选的WHERE子句。
 */
public class UpdateNode extends StatementNode {
    /**
     * 需要被更新的表的名称。
     */
    private final String tableName;

    /**
     * SET子句中的赋值表达式列表。
     * 列表中的每个ExpressionNode都代表一个赋值操作，例如 `column = value`。
     */
    private final List<ExpressionNode> setClause;

    /**
     * WHERE子句，用于指定更新操作的目标行。
     * 如果为 null，表示更新表中的所有行。
     */
    private final ExpressionNode whereClause;

    /**
     * UpdateNode的构造函数。
     *
     * @param position    该UPDATE语句在原始SQL查询中的位置信息。
     * @param tableName   要更新的表的名称。
     * @param setClause   一个包含所有SET赋值操作的 {@link ExpressionNode} 列表。
     * @param whereClause 代表WHERE条件的 {@link ExpressionNode}，可以为null。
     */
    public UpdateNode(Position position, String tableName, List<ExpressionNode> setClause, ExpressionNode whereClause) {
        super(position);
        this.tableName = tableName;
        this.setClause = setClause;
        this.whereClause = whereClause;
    }

    /**
     * 获取此AST节点代表的语句类型。
     *
     * @return 字符串 "UPDATE"。
     */
    @Override
    public String getStatementType() {
        return "UPDATE";
    }

    /**
     * 获取要更新的表的名称。
     *
     * @return 表名字符串。
     */
    public String getTableName() {
        return tableName;
    }

    /**
     * 获取SET子句中的所有赋值表达式。
     *
     * @return 一个包含 {@link ExpressionNode} 的列表。
     */
    public List<ExpressionNode> getSetClause() {
        return setClause;
    }

    /**
     * 获取WHERE子句的表达式。
     *
     * @return 代表WHERE条件的 {@link ExpressionNode}，如果不存在则返回null。
     */
    public ExpressionNode getWhereClause() {
        return whereClause;
    }

    /**
     * 【新增】覆盖 toString 方法以提供清晰的AST展示。
     * 将此节点的内容格式化为易于阅读的字符串，常用于调试或日志记录。
     *
     * @return 该UpdateNode的字符串表示形式。
     */
    @Override
    public String toString() {
        // 将SET子句中的所有表达式转换为字符串，并用 ", " 连接
        String setClauses = setClause.stream()
                .map(ExpressionNode::toString)
                .collect(Collectors.joining(", "));
        // 构建最终的输出字符串
        return "UpdateNode{\n" +
                "    tableName='" + tableName + "',\n" +
                "    setClause=[" + setClauses + "],\n" +
                "    whereClause=" + (whereClause != null ? whereClause.toString() : "无") + "\n" +
                "}";
    }
}